﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Data;
using System.Web;
using System.Xml;
using Newtonsoft.Json.Linq;

namespace Alfred
{
	class Allocine
	{
		public string codePostal { get; set; }

		public List<Seance> seances { get; set; }
		public string film { get; set; }

		public string currentFilm { get; set; }
		public string currentCinema { get; set; }

		public static List<Allocine> GetMoviesSchedule(string codePostal)
		{
			string query = "http://api.allocine.fr/rest/v3/showtimelist?partner=YW5kcm9pZC12M3M&q=61282&format=json&zip=" + codePostal;
			List<Allocine> list = new List<Allocine>();

			var request = new WebClient();
			request.Encoding = Encoding.UTF8;
			string jsonString = request.DownloadString(query);
			JObject json = JObject.Parse(jsonString);
			var j = json["feed"]["theaterShowtimes"];
			foreach (JToken jt in j)
			{
				var theater = jt["place"]["theater"]["name"].ToString();
				var movies = jt["movieShowtimes"];
				foreach (JToken movieToken in movies)
				{
					string s = String.Format("{0:yyyy-MM-dd}", DateTime.Now);
					var movie2 = movieToken["onShow"]["movie"];
					try
					{
						var horaires = movieToken["scr"];
						foreach (JToken tk2 in horaires)
						{
							string d3 = tk2["d"].ToString();
							if (d3 == s)
							{
								string film = movie2["title"].ToString();
								Allocine allo = list.SingleOrDefault(p => p.film == film);
								list.Remove(allo);
								if (allo == null)
									allo = new Allocine() { seances = new List<Seance>(), film = movie2["title"].ToString() };
								if (!allo.seances.Exists(sc => sc.Cinema == theater))
									allo.seances.Add(new Seance() { Cinema = theater, Heures = new Dictionary<string, string>() });
								foreach (JToken jt3 in tk2["t"])
								{
									Seance sceance = allo.seances.Single(sc => sc.Cinema == theater);
									if (sceance.Heures.Keys.Count == 0 || sceance.Heures.Keys.SingleOrDefault(ho => ho == jt3["$"].ToString()) == null)
									{
										string vo = (bool.Parse(movieToken["version"]["original"].ToString())) ? "VO" : "VF";
										allo.seances.Single(sc => sc.Cinema == theater).Heures.Add(jt3["$"].ToString(), vo);
									}
								}
								list.Add(allo);
							}
						}
					}
					catch (Exception e)
					{
                        string stringError = e.Message;
                        continue;
					}
				}
			}
			return list;
		}

		public static void AddTheatersToXML(string codePostal)
		{
			
			XmlDocument xml = new XmlDocument();

			string path = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;
			xml.Load(path + "\\Grammaire.grxml");

			XmlNodeList rules = xml.GetElementsByTagName("rule");
			XmlNode oneOfFilm = null;

			foreach (XmlNode node in rules)
			{
				if (node.Attributes["id"].Value == "cinema")
				{
					oneOfFilm = node.ChildNodes[0].ChildNodes[0].ChildNodes[0];
				}
			}

			oneOfFilm.RemoveAll();
            List<string> listCine = new List<string>();

			xml.Save(path + "\\Grammaire.grxml");
		}

        public static List<string> GetAllCinemaListString()
        {
            List<string> list = new List<string>();
            for (int i = 1; i < 21; i++)
            {
                List<Allocine> allocine = GetMoviesSchedule("750" + i.ToString().PadLeft(2, '0'));
                foreach (Allocine a in allocine)
                {
                    foreach (Seance s in a.seances)
                    {
                        if (!list.Exists(l => l == s.Cinema))
                        {
                            list.Add(s.Cinema);
                        }
                    }
                }
            }
            return list;
        }

		public static Allocine GetMovieInfo(string movie, string codePostal)
		{
			List<Allocine> list = GetMoviesSchedule(codePostal);
			Allocine al = list.SingleOrDefault(a => a.film == movie.TrimEnd(' '));

			return al;
		}

		public static List<string> GetMoviesList(string codePostal)
		{
			List<Allocine> list = GetMoviesSchedule(codePostal);
			return list.Select(al => al.film).ToList();
		}

        public static List<string> GetAllMovieListString()
        {
            List<string> list = new List<string>();
            for (int i = 1; i < 21; i++)
            {
                foreach (string s in GetMoviesList("750" + i.ToString().PadLeft(2, '0')))
                {
                    if (!list.Exists(f => f == s))
                        list.Add(s);
                }
            }
            return list;
        }

		public static string StringMovies(string codePostal)
		{
			string s = "Les films qui passent dans le " + codePostal + " sont : ";
			List<string> films = GetMoviesList(codePostal);

			foreach (string film in films)
				s += film + ", ";
			return s;
		}

		public string StringCinemas()
		{
			string s = "Ce film passe aux cinémas ";
			int i = 0;

			List<string> cinemas = seances.Select(se => se.Cinema).ToList();
			foreach (string cine in cinemas)
			{

				s += cine;
				if (i < cinemas.Count - 1)
					s += ", ";
				i++;
			}
			return s;
		}

        public string StringSeance(string cinema = "", string vo = "")
		{
			string s = "Ce film passe au cinema ";
			List<string> heuresVO = new List<string>();
			List<string> heuresVF = new List<string>();

			if (cinema != "")
			{
				Seance seance = seances.Single(se => se.Cinema == cinema);
				s += cinema + " à ";

				heuresVO = seance.Heures.Where(he => he.Value == "VO").Select(heu => heu.Key).ToList();
				heuresVF = seance.Heures.Where(he => he.Value == "VF").Select(heu => heu.Key).ToList();

				if (vo == "VO" || vo == "")
				{
					foreach (string h in heuresVO)
						s += h + ", ";
					s += " en " + vo;
				}

				if (vo == "VF" || vo == "")
				{
					foreach (string h in heuresVF)
						s += h + ", ";
					s += " en " + vo;
				}
			}
			else
			{
				int i = 0;
				foreach (Seance seance in seances)
				{
					s += seance.Cinema + " à ";
					heuresVO = seance.Heures.Where(he => he.Value == "VO").Select(heu => heu.Key).ToList();
					heuresVF = seance.Heures.Where(he => he.Value == "VF").Select(heu => heu.Key).ToList();

					if ((heuresVO.Count != 0) && (vo == "VO" || vo == ""))
					{
						foreach (string h in heuresVO)
							s += h.Replace(":", " heure ") + ", ";
						s += " en VO, ";
					}

					if ((heuresVF.Count != 0) && (vo == "VF" || vo == ""))
					{
						foreach (string h in heuresVF)
							s += h.Replace(":", " heure ") + ", ";
						s += " en VF, ";
					}
					if (i < seances.Count - 1)
						s += " au ";
				}
			}
			return s;
		}
	}
}
